home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / Vperf5.1-src.lha / Viewperf5.1 / viewperf / evtF.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-17  |  12.6 KB  |  365 lines

  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. #if defined(WIN32) || defined(OS2) | defined(__amigaos__)
  5. #define MAXINT 0x7fffffff
  6. #else
  7. #include <values.h>
  8. #endif
  9.  
  10. #ifdef WIN32
  11. #include <windows.h>
  12. #endif
  13.  
  14. #include <GL/gl.h>
  15.  
  16. #ifdef XWINDOWS
  17. #include <GL/glx.h>
  18. #endif
  19.  
  20. #ifdef OS2
  21. #include "aux.h"
  22. #elif __amigaos__
  23. #include <gl/glaux.h>
  24. #endif
  25.  
  26. #include "viewperf.h"
  27. #include "vpDefine.h"
  28.  
  29. extern char teststring[][32];
  30. extern struct EventBlock eventblock;
  31.  
  32. #if !defined(MP)
  33. #define START_THREADS(pevent)
  34. #define WAIT_FOR_THREADS(pevent)
  35. #define WAIT_FOR_START(pevent, threadNum)
  36. #define SET_THREAD_DONE(pevent, threadNum)
  37.  
  38. #elif defined(WIN32)
  39. #define START_THREADS(pevent) { \
  40.         struct ThreadBlock *tb; \
  41.         int thread; \
  42.         tb = &pevent->tb[1]; \
  43.             for (thread = 1; thread < pevent->threads; thread++, tb++) \
  44.             SetEvent(tb->startEvent); \
  45.         }
  46.  
  47. #define WAIT_FOR_THREADS(pevent) { \
  48.         struct ThreadBlock *tb; \
  49.         int thread; \
  50.         tb = &pevent->tb[1]; \
  51.             for (thread = 1; thread < pevent->threads; thread++, tb++) \
  52.             WaitForSingleObject(tb->doneEvent, INFINITE); \
  53.         }
  54.  
  55. #define WAIT_FOR_START(pevent, threadNum) \
  56.         WaitForSingleObject(pevent->tb[threadNum].startEvent, INFINITE)
  57.  
  58. #define SET_THREAD_DONE(pevent, threadNum) \
  59.         SetEvent(pevent->tb[threadNum].doneEvent)
  60.  
  61. #elif defined(SOME_OTHER_OS)
  62. /* Put os specific code to:
  63.     Control MACRO to start all threads
  64.     Control MACRO to wait for the completion of all threads
  65.     Thread MACRO to wait for start
  66.     Thread MACRO to indicate completion
  67. */
  68. #endif
  69.  
  70. extern GLfloat iang, jang, kang;
  71.  
  72. void FUNCTION(int threadNum)
  73. {
  74.         struct EventBlock *pevent = &eventblock;
  75.         GLenum err;
  76.         float period, fps;
  77.         float minperiod = pevent->minperiod;
  78.         int numframes;
  79.         int oldnumframes;
  80.         int frameCountBumped=VP_FALSE;
  81.         #ifdef WALKTHRU
  82.         GLfloat **walkthru = pevent->walkthru;
  83.         #endif
  84.         #ifdef MOTION_BLUR
  85.         GLfloat decay_frames = pevent->blur_frames;
  86.         #endif
  87.         #ifdef FS_ANTIALIASING
  88.         int jit;
  89.         int redraws;
  90.         struct vector *jitter;
  91.         #endif
  92.         /* Begin Windowing system dependent */
  93.         #ifdef WIN32
  94.         HDC display = pevent->display;
  95.         #elif !defined(OS2) && !defined(__amigaos__)
  96.         Display *pdisplay = pevent->display;
  97.         Window pwin = pevent->window;
  98.         #endif
  99.         /* End Windowing system dependent */
  100.         #ifdef DISPLAY_LIST
  101.         GLuint list;
  102.         #endif
  103.         int framenum;
  104.         struct RenderBlock *renderblock = pevent->rb;
  105.         void (*func)(struct ThreadBlock *rb) = pevent->func;
  106.         #ifdef DISPLAY_LIST
  107.         #ifdef WIN32
  108.         void (APIENTRY *glCallListP)(GLuint);
  109.         #else
  110.         void (*glCallListP)(GLuint);
  111.         #endif
  112.         #endif
  113.         #if defined(WIN32)
  114.         void (APIENTRY *swapOrFinish)(HDC);
  115.         #elif defined(OS2) || defined(__amigaos__)
  116.         void (*swapOrFinish)(void);
  117.         #else
  118.         void (*swapOrFinish)(Display*, GLXDrawable);
  119.         #endif
  120.         enum { Prime, Calibrate, Measure, Done } testState;
  121.         GLfloat minCalibratePeriod = 1.0;
  122.         GLfloat measuredFramerate;
  123.         GLfloat *trans = pevent->trans;
  124.         GLfloat ltrans0 = trans[0];
  125.         GLfloat ltrans1 = trans[1] * (GLfloat) 0.98;
  126.         GLfloat ltrans2 = trans[2];
  127.         GLfloat ltrans3 = trans[3] * ZTRANS_SCALE;
  128.         GLfloat translateX = (pevent->clip) ? -pevent->center[0] : 0.0;
  129.         GLfloat translateY = (pevent->clip) ? -pevent->center[1] : 0.0;
  130.         GLfloat translateZ = -ltrans3;
  131.         GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
  132.  
  133.         if (pevent->zbuffer)
  134.             clearMask |= GL_DEPTH_BUFFER_BIT;
  135.  
  136.         #if defined(FS_ANTIALIASING) && !defined(MOTION_BLUR)
  137.             clearMask |= GL_ACCUM_BUFFER_BIT;
  138.         #endif
  139.  
  140.         #ifdef MP
  141.         /* Set up this thread to draw to the window */
  142.         if (threadNum) {
  143.                 #if defined(WIN32)
  144.                 HDC dc;
  145.                 dc = GetDC(pevent->window);
  146.                 wglMakeCurrent(dc, pevent->tb[threadNum].rc);
  147.                 #elif defined(SOME_OTHER_OS)
  148.                 /* Put os specific code to:
  149.                  * MakeCurrent to context for this thread
  150.                  */
  151.                 #endif
  152.         }
  153.         #endif
  154.  
  155.         glFinish();
  156.  
  157.         /* =================================================== */
  158.         /* Create display list, if called for                  */
  159.         /* =================================================== */
  160.     #ifdef DISPLAY_LIST
  161.         if (threadNum) {
  162.                 WAIT_FOR_START(pevent, threadNum);
  163.         } else {
  164.                 startclock();
  165.                 START_THREADS(pevent);
  166.         }
  167.         glCallListP = glCallList;
  168.         list = glGenLists(1);
  169.         glNewList(list, GL_COMPILE);
  170.         (*func)(&pevent->tb[threadNum]);
  171.         glEndList();
  172.         glFinish();
  173.  
  174.         if (threadNum) {
  175.                 SET_THREAD_DONE(pevent, threadNum);
  176.         } else {
  177.                 WAIT_FOR_THREADS(pevent);
  178.                 period = stopclock();
  179.                 fprintf(stdout,"%#8.3g\tsec (DL Build)\t--\t%s\n", roundit(period), pevent->teststring);
  180.         }
  181.     #endif
  182.  
  183.         /* =================================================== */
  184.         /* New all-purpose test loop                           */
  185.         /* Four stages: Prime, Calibrate, Measure, Done        */
  186.         /* =================================================== */
  187.         testState = Prime;
  188.         /* Slave threads will stay in Prime state for their    */
  189.         /* entire existences (that is, until the master kills  */
  190.         /* them.)  That's why numframes is set to MAXINT...    */
  191.         numframes = threadNum ? MAXINT : 1;
  192.         if (pevent->doubleBuffer && threadNum == 0) {
  193.             #if defined(WIN32)
  194.                 swapOrFinish = SwapBuffers;
  195.             #elif defined(OS2) || defined(__amigaos__)
  196.                 swapOrFinish = auxSwapBuffers;
  197.             #else
  198.                 swapOrFinish = glXSwapBuffers;
  199.             #endif
  200.         } else {
  201.             #if defined(WIN32)
  202.                 swapOrFinish = FinishFrame;
  203.             #elif defined(OS2)
  204.                 swapOrFinish = FinishFrame;
  205.             #else
  206.                 swapOrFinish = FinishFrame;
  207.             #endif
  208.         }
  209.         while (testState != Done) {
  210.  
  211.                 if (threadNum == 0)  {
  212.                     startclock();
  213.  
  214.                  #ifndef WALKTHRU
  215.                     iang = 0.0;
  216.                     jang = 0.0;
  217.                     kang = 0.0;
  218.                 #endif
  219.         }
  220.  
  221.             #if defined(MOTION_BLUR) || defined(FS_ANTIALIASING)
  222.                 glClear(GL_ACCUM_BUFFER_BIT);
  223.             #endif
  224.                 for (framenum = 0; framenum < numframes; framenum++) {
  225.                     #ifdef MP
  226.                         if (threadNum) {
  227.                                 WAIT_FOR_START(pevent, threadNum);
  228.                         } else {
  229.                                 glClear(clearMask);
  230.                                 glFinish();
  231.                                 pevent->walkthruFrame = framenum;
  232.                                 START_THREADS(pevent);
  233.                         }
  234.                     #else
  235.                         glClear(clearMask);
  236.                         pevent->walkthruFrame = framenum;
  237.                     #endif
  238.  
  239.                     #ifdef FS_ANTIALIASING
  240.                         jitter = pevent->jitter;
  241.                         redraws = pevent->redraws;
  242.                         for (jit = 0; jit <= redraws; jit++) {
  243.                                 glPushMatrix();
  244.                                 glTranslatef(jitter[jit].x, jitter[jit].y, 0);
  245.                     #else
  246.                                 glPushMatrix();
  247.                     #endif
  248.                             #ifdef WALKTHRU
  249.                                 glLoadMatrixf(walkthru[pevent->walkthruFrame]); 
  250.                             #else
  251.                                 glTranslatef(translateX, translateY, translateZ);
  252.                                 glRotatef(jang, 0.0, 1.0, 0.0);
  253.                                 glRotatef(iang, 1.0, 0.0, 0.0);
  254.                                 glRotatef(kang, 0.0, 0.0, 1.0);
  255.                                 glTranslatef(-ltrans0, -ltrans1, -ltrans2);
  256.                             #endif
  257.                             #ifdef DISPLAY_LIST
  258.                                 (*glCallListP)(list);
  259.                             #else
  260.                                 (*func)(&pevent->tb[threadNum]);
  261.                             #endif
  262.                     #ifdef FS_ANTIALIASING
  263.                                 glAccum(GL_ACCUM, 1.0/redraws);
  264.                                 glPopMatrix();
  265.                         }
  266.                     #else
  267.                                 glPopMatrix();
  268.                     #endif
  269.  
  270.                     #if defined(MOTION_BLUR)
  271.                         glAccum(GL_ACCUM, 1.0);
  272.                     #endif
  273.  
  274.                     #if defined(MOTION_BLUR) || defined(FS_ANTIALIASING)
  275.                         glAccum(GL_RETURN, 1.0);
  276.                     #endif
  277.  
  278.                     #ifdef MP
  279.                         if (threadNum) {
  280.                                 glFinish();
  281.                                 SET_THREAD_DONE(pevent, threadNum);
  282.                         } else {
  283.                                 WAIT_FOR_THREADS(pevent);
  284.                     #endif
  285.                             #if defined(WIN32)
  286.                                 (*swapOrFinish)(display);
  287.                             #elif defined(OS2) || defined(__amigaos__)
  288.                                 (*swapOrFinish)();
  289.                             #else
  290.                                 (*swapOrFinish)(pdisplay, pwin);
  291.                             #endif
  292.  
  293.                       #ifndef WALKTHRU
  294.                           iang -= 1.0;
  295.                           jang += 5.0;
  296.                           kang += 0.5;
  297.                       #endif
  298.                     #ifdef MP
  299.                         }
  300.                     #endif
  301.                 }
  302.               #ifndef WIN32
  303.                 if (pevent->doubleBuffer) glFinish();
  304.               #endif
  305.                 period = stopclock();
  306.  
  307.                 switch (testState) {
  308.                 case Prime:
  309.                         /* Finished priming the pump, time to calibrate, if */
  310.                         /* a specific number of frames has not been set     */
  311.                         if (pevent->numframes == 0) {
  312.                                 testState = Calibrate;
  313.                         } else {
  314.                                 /* Already given a specified number of      */
  315.                                 /* frames to draw.  Go directly to Measure  */
  316.                                 testState = Measure;
  317.                                 numframes = pevent->numframes;
  318.                         }
  319.                         break;
  320.                 case Calibrate:
  321.                         if (period < minCalibratePeriod) {
  322.                                 numframes *= 2;
  323.                                 if (pevent->numframes != 0)
  324.                                         numframes = MIN(numframes, pevent->numframes);
  325.                         } else if (period >= minperiod && pevent->numframes == 0) {
  326.                                 /* Well, we fulfilled our test period during */
  327.                                 /* Calibration, so we don't need to run again*/
  328.                                 testState = Done;
  329.                         } else {
  330.                                 testState = Measure;
  331.                                 if (pevent->numframes == 0) {
  332.                                         numframes = (int)ceil((float)numframes * minperiod / period);
  333.                                 } else {
  334.                                         numframes = pevent->numframes;
  335.                                 }
  336.                         }
  337.                         break;
  338.                 case Measure:
  339.                         testState = Done;
  340.                         break;
  341.                 case Done:
  342.                         /* We should NEVER be here! */
  343.                         fprintf(stdout, "viewperf: Major problem in event loop!\n");
  344.                         exit(-1);
  345.                         break;
  346.                 }
  347.         }
  348.  
  349.         fprintf(stdout,
  350.                 "\n\t\tNumber of frames run: %d, Test period: %f (sec)\n",
  351.                 numframes, period);
  352.         fprintf(stdout,
  353.                 "%#8.3g\tframes/sec\t--\t%s\n", 
  354.                 roundit((float)numframes/period), pevent->teststring);
  355.  
  356.         if (err = glGetError())
  357.                 fprintf(stdout, 
  358.                         "<<WARNING>>: glError %s. The above results may be invalid\n",
  359.                         error2str(err));
  360.  
  361.     #ifdef DISPLAY_LIST
  362.         glDeleteLists(list, 1);
  363.     #endif
  364. }
  365.